home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 June: Reference Library / Dev.CD Jun 96 RL / Dev.CD Jun 96 RL.toast / What's New? / Development Kits / Apple Game Sprockets DR1 / Examples / SoundSprocketTest / TS3TestLoLevel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-24  |  30.0 KB  |  1,325 lines  |  [TEXT/MPS ]

  1. /*
  2.  *    File:        TS3TestLoLevel.c
  3.  *    Author:        Dan Venolia
  4.  *
  5.  *    Copyright © 1996 Apple Computer, Inc.
  6.  */
  7.  
  8. #include <assert.h>
  9. #include <math.h>
  10. #include <string.h>
  11.  
  12. #include <Dialogs.h>
  13. #include <Fonts.h>
  14. #include <Timer.h>
  15.  
  16. #include "TS3Resource.h"
  17. #include "TS3Sound.h"
  18. #include "TS3TestLoLevel.h"
  19. #include "TS3Utils.h"
  20. #include "TS3Window.h"
  21.  
  22. #include "SoundSprocket.h"
  23.  
  24.  
  25. typedef struct TTestLoLevelData {
  26.     float            duration;
  27.     
  28.     UInt32            cpuLoad1;
  29.     UInt32            cpuLoad2;
  30.     Boolean            cpuLoadRange;
  31.     
  32.     UInt32            medium;
  33.     
  34.     float            humidity1;
  35.     float            humidity2;
  36.     Boolean            humidityRange;
  37.     
  38.     float            roomSize1;
  39.     float            roomSize2;
  40.     Boolean            roomSizeRange;
  41.     
  42.     float            roomReflectivity1;
  43.     float            roomReflectivity2;
  44.     Boolean            roomReflectivityRange;
  45.     
  46.     float            reverbAttenuation1;
  47.     float            reverbAttenuation2;
  48.     Boolean            reverbAttenuationRange;
  49.     
  50.     UInt32            sourceMode;
  51.     
  52.     float            referenceDistance1;
  53.     float            referenceDistance2;
  54.     Boolean            referenceDistanceRange;
  55.     
  56.     float            coneAngleDeg1;
  57.     float            coneAngleDeg2;
  58.     Boolean            coneAngleDegRange;
  59.     
  60.     float            coneAttenuation1;
  61.     float            coneAttenuation2;
  62.     Boolean            coneAttenuationRange;
  63.     
  64.     float            longitudeDeg1;
  65.     float            longitudeDeg2;
  66.     Boolean            longitudeDegRange;
  67.     
  68.     float            latitudeDeg1;
  69.     float            latitudeDeg2;
  70.     Boolean            latitudeDegRange;
  71.     
  72.     float            distance1;
  73.     float            distance2;
  74.     Boolean            distanceRange;
  75.     
  76.     float            projectionAngleDeg1;
  77.     float            projectionAngleDeg2;
  78.     Boolean            projectionAngleDegRange;
  79.     
  80.     float            sourceVelocity1;
  81.     float            sourceVelocity2;
  82.     Boolean            sourceVelocityRange;
  83.     
  84.     float            listenerVelocity1;
  85.     float            listenerVelocity2;
  86.     Boolean            listenerVelocityRange;
  87.     
  88.     float            coneAngleCos1;
  89.     float            coneAngleCos2;
  90.     
  91.     float            longitude1;
  92.     float            longitude2;
  93.     
  94.     float            latitude1;
  95.     float            latitude2;
  96.     
  97.     float            projectionAngle1;
  98.     float            projectionAngle2;
  99. } TTestLoLevelData;
  100.  
  101.  
  102. static DialogPtr                gTestLoLevelDialog                = NULL;
  103. static UserItemUPP                gTestLoLevelProgressUserItem    = NULL;
  104. static UInt32                    gTestLoLevelCPULoadLimit;
  105. static TTestLoLevelData            gTestLoLevelData;
  106.  
  107. static UnsignedWide                gTestLoLevelCycleStart;
  108. static float                    gTestLoLevelInterpolant            = 0;
  109. static Boolean                    gTestLoLevelForward                = true;
  110.  
  111.  
  112. static WindowMethodPtr TestLoLevel_MetaHandler(
  113.     WindowMethod        inMethod);
  114.  
  115. static void TestLoLevel_GetSleep(
  116.     WindowPtr            inWindow,
  117.     UInt32*                outSleep);
  118.  
  119. static void TestLoLevel_ConsumeEvent(
  120.     WindowPtr            inWindow,
  121.     const EventRecord*    inEvent,
  122.     Boolean*            outConsumed);
  123.  
  124. static pascal void TestLoLevel_ProgressUserItem(
  125.     DialogPtr            inDialog,
  126.     short                inItem);
  127.  
  128. static void TestLoLevel_Interpolate(
  129.     void);
  130.  
  131. static float TestLoLevel_DoInterpolate(
  132.     float                inWhere,
  133.     float                inVal0,
  134.     float                inVal1,
  135.     Boolean                inIsRange);
  136.  
  137. static void TestLoLevel_DeriveData(
  138.     void);
  139.  
  140. static void TestLoLevel_SetDialogFields(
  141.     void);
  142.  
  143. static void TestLoLevel_GetDialogFields(
  144.     void);
  145.  
  146.  
  147. /* =============================================================================
  148.  *        TestLoLevel_Init (external)
  149.  *
  150.  *    Initializes our thing.
  151.  * ========================================================================== */
  152. void TestLoLevel_Init(
  153.     void)
  154. {
  155.     short                itemType;
  156.     Handle                itemHandle;
  157.     Rect                itemBounds;
  158.     Str255                str;
  159.     
  160.     // Make sure we didn't mess up the dialog items
  161.     assert(kLoLevelItem_COUNT == kLoLevelItem_ExpectedCOUNT);
  162.     
  163.     // Grab the maximum CPU load limit value
  164.     gTestLoLevelCPULoadLimit = 999;
  165.     GetCPULoadLimit(&gTestLoLevelCPULoadLimit);
  166.     //• CHECK ERROR
  167.     
  168.     //• TODO: Read in gTestLoLevelData from preferences
  169.     
  170.     // Set the default test setup
  171.     gTestLoLevelData.duration                = 2.0;
  172.     
  173.     gTestLoLevelData.cpuLoad1                =
  174.     gTestLoLevelData.cpuLoad2                = 0;
  175.     gTestLoLevelData.cpuLoadRange            = false;
  176.     
  177.     gTestLoLevelData.medium                    = kMediumAir;
  178.     
  179.     gTestLoLevelData.humidity1                =
  180.     gTestLoLevelData.humidity2                = 0.0;
  181.     gTestLoLevelData.humidityRange            = false;
  182.     
  183.     gTestLoLevelData.roomSize1                =
  184.     gTestLoLevelData.roomSize2                = 0.0;
  185.     gTestLoLevelData.roomSizeRange            = false;
  186.     
  187.     gTestLoLevelData.roomReflectivity1        =
  188.     gTestLoLevelData.roomReflectivity2        = -10.0;
  189.     gTestLoLevelData.roomReflectivityRange    = false;
  190.     
  191.     gTestLoLevelData.reverbAttenuation1        =
  192.     gTestLoLevelData.reverbAttenuation2        = -15.0;
  193.     gTestLoLevelData.reverbAttenuationRange    = false;
  194.     
  195.     gTestLoLevelData.sourceMode                = kSourceModeLocalized;
  196.     
  197.     gTestLoLevelData.referenceDistance1        =
  198.     gTestLoLevelData.referenceDistance2        = 1.0;
  199.     gTestLoLevelData.referenceDistanceRange    = false;
  200.     
  201.     gTestLoLevelData.coneAngleDeg1            =
  202.     gTestLoLevelData.coneAngleDeg2            = 90.0;
  203.     gTestLoLevelData.coneAngleDegRange        = false;
  204.     
  205.     gTestLoLevelData.coneAttenuation1        =
  206.     gTestLoLevelData.coneAttenuation2        = 0.0;
  207.     gTestLoLevelData.coneAttenuationRange    = false;
  208.     
  209.     gTestLoLevelData.longitudeDeg1            =
  210.     gTestLoLevelData.longitudeDeg2            = 0.0;
  211.     gTestLoLevelData.longitudeDegRange        = false;
  212.     
  213.     gTestLoLevelData.latitudeDeg1            = -90.0;
  214.     gTestLoLevelData.latitudeDeg2            = 90.0;
  215.     gTestLoLevelData.latitudeDegRange        = true;
  216.     
  217.     gTestLoLevelData.distance1                =
  218.     gTestLoLevelData.distance2                = 1.0;
  219.     gTestLoLevelData.distanceRange            = false;
  220.     
  221.     gTestLoLevelData.projectionAngleDeg1    =
  222.     gTestLoLevelData.projectionAngleDeg2    = 0.0;
  223.     gTestLoLevelData.projectionAngleDegRange = false;
  224.     
  225.     gTestLoLevelData.sourceVelocity1        =
  226.     gTestLoLevelData.sourceVelocity2        = 0.0;
  227.     gTestLoLevelData.sourceVelocityRange    = false;
  228.     
  229.     gTestLoLevelData.listenerVelocity1        =
  230.     gTestLoLevelData.listenerVelocity2        = 0.0;
  231.     gTestLoLevelData.listenerVelocityRange    = false;
  232.     
  233.     TestLoLevel_DeriveData();
  234.     
  235.     // Grab the dialog
  236.     gTestLoLevelDialog = GetNewDialog(kDlogID_LoLevel, NULL, (WindowPtr) -1);
  237.     assert(gTestLoLevelDialog != NULL);
  238.     
  239.     SetPort(gTestLoLevelDialog);
  240.     TextFont(geneva);
  241.     TextSize(10);
  242.     
  243.     // Set up our method table
  244.     Window_New(gTestLoLevelDialog, TestLoLevel_MetaHandler);
  245.     
  246.     // Do the user items
  247.     GetDialogItem(gTestLoLevelDialog, kLoLevelItem_UpdateHilite, &itemType, &itemHandle, &itemBounds);
  248.     SetDialogItem(gTestLoLevelDialog, kLoLevelItem_UpdateHilite, itemType, (Handle) Utils_GetOKUserItemProc(), &itemBounds);
  249.     
  250.     gTestLoLevelProgressUserItem = NewUserItemProc(TestLoLevel_ProgressUserItem);
  251.     assert(gTestLoLevelProgressUserItem != NULL);
  252.     
  253.     GetDialogItem(gTestLoLevelDialog, kLoLevelItem_Progress, &itemType, &itemHandle, &itemBounds);
  254.     SetDialogItem(gTestLoLevelDialog, kLoLevelItem_Progress, itemType, (Handle) gTestLoLevelProgressUserItem, &itemBounds);
  255.     
  256.     // Show the quality limit
  257.     sprintf((char*) str, "x[0..%ld]", gTestLoLevelCPULoadLimit);
  258.     str[0] = strlen((char*) str)-1;
  259.     
  260.     GetDialogItem(gTestLoLevelDialog, kLoLevelItem_CPULoadUnits, &itemType, &itemHandle, &itemBounds);
  261.     SetDialogItemText(itemHandle, str);
  262.     
  263.     // Set the initial field values
  264.     TestLoLevel_SetDialogFields();
  265.     
  266.     // Select the first field
  267.     SelectDialogItemText(gTestLoLevelDialog, kLoLevelItem_Duration, 0, 32767);
  268.     
  269.     // Show the dialog
  270.     ShowWindow(gTestLoLevelDialog);
  271.     
  272.     // Initialize our cycle timer
  273.     Microseconds(&gTestLoLevelCycleStart);
  274. }
  275.  
  276.  
  277. /* =============================================================================
  278.  *        TestLoLevel_Exit (external)
  279.  *
  280.  *    Cleans up.
  281.  * ========================================================================== */
  282. void TestLoLevel_Exit(
  283.     void)
  284. {
  285.     //• TODO: Save gTestLoLevel to preferences
  286.     
  287.     if (gTestLoLevelDialog != NULL)
  288.     {
  289.         DisposeDialog(gTestLoLevelDialog);
  290.         gTestLoLevelDialog = NULL;
  291.     }
  292.     
  293.     if (gTestLoLevelProgressUserItem != NULL)
  294.     {
  295.         DisposeRoutineDescriptor(gTestLoLevelProgressUserItem);
  296.         gTestLoLevelProgressUserItem = NULL;
  297.     }
  298. }
  299.  
  300.  
  301. /* =============================================================================
  302.  *        TestLoLevel_MetaHandler (internal)
  303.  *
  304.  *    Returns the method function pointer that corresponds to the given ID.
  305.  * ========================================================================== */
  306. WindowMethodPtr TestLoLevel_MetaHandler(
  307.     WindowMethod        inMethod)
  308. {
  309.     WindowMethodPtr        result;
  310.     
  311.     result = NULL;
  312.     
  313.     switch (inMethod)
  314.     {
  315.         case kWindowMethod_GetSleep:
  316.             result = TestLoLevel_GetSleep;
  317.         break;
  318.         
  319.         case kWindowMethod_ConsumeEvent:
  320.             result = TestLoLevel_ConsumeEvent;
  321.         break;
  322.     }
  323.     
  324.     return result;
  325. }
  326.  
  327.  
  328. /* =============================================================================
  329.  *        TestLoLevel_GetSleep (internal)
  330.  *
  331.  *    Returns the sleep time to pass to WaitNextEvent when we're in front.
  332.  * ========================================================================== */
  333. void TestLoLevel_GetSleep(
  334.     WindowPtr            inWindow,
  335.     UInt32*                outSleep)
  336. {
  337.     assert(outSleep != NULL);
  338.     
  339.     *outSleep = 0;
  340. }
  341.  
  342.  
  343. /* =============================================================================
  344.  *        TestLoLevel_ConsumeEvent (internal)
  345.  *
  346.  *    Called for each event when this is the front window.
  347.  * ========================================================================== */
  348. void TestLoLevel_ConsumeEvent(
  349.     WindowPtr            inWindow,
  350.     const EventRecord*    inEvent,
  351.     Boolean*            outConsumed)
  352. {
  353.     short                itemType;
  354.     Handle                itemHandle;
  355.     Rect                itemBounds;
  356.     ControlHandle        updateButton;
  357.     Boolean                consumed;
  358.     Boolean                passToDialog;
  359.     WindowPtr            window;
  360.     short                item;
  361.     unsigned long        timeout;
  362.     UnsignedWide        now;
  363.     
  364.     assert(inEvent != NULL);
  365.     assert(outConsumed != NULL);
  366.     
  367.     consumed = false;
  368.     passToDialog = true;
  369.     
  370.     // We want to handle some events ourself
  371.     switch (inEvent->what)
  372.     {
  373.         case keyDown:
  374.         case autoKey:
  375.             passToDialog = false;
  376.             
  377.             if (inEvent->modifiers & cmdKey)
  378.             {
  379.                 if (inEvent->what != autoKey)
  380.                 {
  381.                     switch (inEvent->message & charCodeMask)
  382.                     {
  383.                         case '.':
  384.                             // anything here?
  385.                         break;
  386.                     }
  387.                 }
  388.             }
  389.             else
  390.             {
  391.                 switch (inEvent->message & charCodeMask)
  392.                 {
  393.                     case 0x08:  // backspace
  394.                     case 0x09:  // tab
  395.                     case 0x1C:  // cursor left
  396.                     case 0x1D:  // cursor right
  397.                     case 0x1E:  // cursor up
  398.                     case 0x1F:  // cursor down
  399.                     case '.':
  400.                     case '-':
  401.                     case '0':
  402.                     case '1':
  403.                     case '2':
  404.                     case '3':
  405.                     case '4':
  406.                     case '5':
  407.                     case '6':
  408.                     case '7':
  409.                     case '8':
  410.                     case '9':
  411.                         // Pass it to the dialog
  412.                         passToDialog = true;
  413.                     break;
  414.                     
  415.                     case 0x03:  // enter
  416.                     case 0x0D:  // return
  417.                         if (inEvent->what != autoKey)
  418.                         {
  419.                             // Update button equivalent
  420.                             GetDialogItem(gTestLoLevelDialog, kLoLevelItem_Update, &itemType, &itemHandle, &itemBounds);
  421.                             updateButton = (ControlHandle) itemHandle;
  422.                             
  423.                             if ((*updateButton)->contrlHilite == 0)
  424.                             {
  425.                                 HiliteControl(updateButton, 1);
  426.                                 
  427.                                 timeout = TickCount()+6;
  428.                                 while (TickCount() < timeout) /* wait */;
  429.                                 
  430.                                 HiliteControl(updateButton, 0);
  431.                                 
  432.                                 TestLoLevel_GetDialogFields();
  433.                                 
  434.                                 consumed = true;
  435.                             }
  436.                         }
  437.                     break;
  438.                     
  439.                     default:
  440.                         SysBeep(10);
  441.                         consumed = true;
  442.                 }
  443.             }
  444.         break;
  445.         
  446.         case nullEvent:
  447.             // Find where we are in the cycle (0 is start, 1 is end)
  448.             Microseconds(&now);
  449.             gTestLoLevelInterpolant = Utils_Interval(&gTestLoLevelCycleStart, &now) / gTestLoLevelData.duration;
  450.             
  451.             // Are we past the end of the cycle?
  452.             if (gTestLoLevelInterpolant > 1.0)
  453.             {
  454.                 gTestLoLevelCycleStart = now;
  455.                 gTestLoLevelForward = !gTestLoLevelForward;
  456.                 gTestLoLevelInterpolant = 0.0;
  457.             }
  458.             
  459.             // Reverse it on every other cycle
  460.             if (!gTestLoLevelForward)
  461.             {
  462.                 gTestLoLevelInterpolant = 1.0-gTestLoLevelInterpolant;
  463.             }
  464.             
  465.             TestLoLevel_Interpolate();
  466.         break;
  467.     }
  468.     
  469.     // Do dialog stuff
  470.     if (passToDialog)
  471.     {
  472.         consumed = IsDialogEvent(inEvent);
  473.         if (consumed)
  474.         {
  475.             if (DialogSelect(inEvent, &window, &item))
  476.             {
  477.                 switch (item)
  478.                 {
  479.                     case kLoLevelItem_Update:
  480.                         TestLoLevel_GetDialogFields();
  481.                     break;
  482.                 }
  483.             }
  484.         }
  485.     }
  486.     
  487.     // Return the result
  488.     *outConsumed = consumed;
  489. }
  490.  
  491.  
  492. /* =============================================================================
  493.  *        TestLoLevel_ProgressUserItem (internal)
  494.  *
  495.  *    Draws the user item used for progress bar, based on gTestLoLevelInterpolant.
  496.  * ========================================================================== */
  497. pascal void TestLoLevel_ProgressUserItem(
  498.     DialogPtr            inDialog,
  499.     short                inItem)
  500. {
  501.     short                itemType;
  502.     Handle                itemHandle;
  503.     Rect                itemBounds;
  504.     short                size;
  505.     Rect                leftWhite;
  506.     Rect                rightWhite;
  507.     Rect                indicator;
  508.     
  509.     GetDialogItem(inDialog, inItem, &itemType, &itemHandle, &itemBounds);
  510.     
  511.     FrameRect(&itemBounds);
  512.     
  513.     InsetRect(&itemBounds, 1, 1);
  514.     size = itemBounds.bottom-itemBounds.top;
  515.     
  516.     indicator = itemBounds;
  517.     indicator.left = itemBounds.left + (long) (gTestLoLevelInterpolant*(itemBounds.right-itemBounds.left-size) + 0.5);
  518.     indicator.right = indicator.left+size;
  519.     
  520.     leftWhite = itemBounds;
  521.     leftWhite.right = indicator.left;
  522.     
  523.     rightWhite = itemBounds;
  524.     rightWhite.left = indicator.right;
  525.     
  526.     FrameRect(&indicator);
  527.     
  528.     InsetRect(&indicator, 1, 1);
  529.     FillRect(&indicator, &qd.gray);
  530.     
  531.     EraseRect(&leftWhite);
  532.     EraseRect(&rightWhite);
  533. }
  534.  
  535.  
  536. /* =============================================================================
  537.  *        TestLoLevel_Interpolate (internal)
  538.  *
  539.  *    Changes the sound channel to the correct values for the point between
  540.  *    zero and one determined by gTestLoLevelInterpolant.
  541.  * ========================================================================== */
  542. void TestLoLevel_Interpolate(
  543.     void)
  544. {
  545.     Snd3DInfo            snd3DInfo;
  546.     
  547.     snd3DInfo.cpuLoad = (UInt32) (TestLoLevel_DoInterpolate(
  548.             gTestLoLevelInterpolant,
  549.             (float) gTestLoLevelData.cpuLoad1,
  550.             (float) gTestLoLevelData.cpuLoad2,
  551.             gTestLoLevelData.cpuLoadRange) + 0.5);
  552.     
  553.     snd3DInfo.medium = gTestLoLevelData.medium;
  554.     
  555.     snd3DInfo.humidity = TestLoLevel_DoInterpolate(
  556.             gTestLoLevelInterpolant,
  557.             gTestLoLevelData.humidity1,
  558.             gTestLoLevelData.humidity2,
  559.             gTestLoLevelData.humidityRange);
  560.     
  561.     snd3DInfo.roomSize = TestLoLevel_DoInterpolate(
  562.             gTestLoLevelInterpolant,
  563.             gTestLoLevelData.roomSize1,
  564.             gTestLoLevelData.roomSize2,
  565.             gTestLoLevelData.roomSizeRange);
  566.     
  567.     snd3DInfo.roomReflectivity = TestLoLevel_DoInterpolate(
  568.             gTestLoLevelInterpolant,
  569.             gTestLoLevelData.roomReflectivity1,
  570.             gTestLoLevelData.roomReflectivity2,
  571.             gTestLoLevelData.roomReflectivityRange);
  572.     
  573.     snd3DInfo.reverbAttenuation = TestLoLevel_DoInterpolate(
  574.             gTestLoLevelInterpolant,
  575.             gTestLoLevelData.reverbAttenuation1,
  576.             gTestLoLevelData.reverbAttenuation2,
  577.             gTestLoLevelData.reverbAttenuationRange);
  578.     
  579.     snd3DInfo.sourceMode = gTestLoLevelData.sourceMode;
  580.     
  581.     snd3DInfo.referenceDistance = TestLoLevel_DoInterpolate(
  582.             gTestLoLevelInterpolant,
  583.             gTestLoLevelData.referenceDistance1,
  584.             gTestLoLevelData.referenceDistance2,
  585.             gTestLoLevelData.referenceDistanceRange);
  586.     
  587.     snd3DInfo.coneAngleCos = TestLoLevel_DoInterpolate(
  588.             gTestLoLevelInterpolant,
  589.             gTestLoLevelData.coneAngleCos1,
  590.             gTestLoLevelData.coneAngleCos2,
  591.             gTestLoLevelData.coneAngleDegRange);
  592.     
  593.     snd3DInfo.coneAttenuation = TestLoLevel_DoInterpolate(
  594.             gTestLoLevelInterpolant,
  595.             gTestLoLevelData.coneAttenuation1,
  596.             gTestLoLevelData.coneAttenuation2,
  597.             gTestLoLevelData.coneAttenuationRange);
  598.     
  599.     snd3DInfo.currentLocation.longitude = TestLoLevel_DoInterpolate(
  600.             gTestLoLevelInterpolant,
  601.             gTestLoLevelData.longitude1,
  602.             gTestLoLevelData.longitude2,
  603.             gTestLoLevelData.longitudeDegRange);
  604.     
  605.     snd3DInfo.currentLocation.latitude = TestLoLevel_DoInterpolate(
  606.             gTestLoLevelInterpolant,
  607.             gTestLoLevelData.latitude1,
  608.             gTestLoLevelData.latitude2,
  609.             gTestLoLevelData.latitudeDegRange);
  610.     
  611.     snd3DInfo.currentLocation.distance = TestLoLevel_DoInterpolate(
  612.             gTestLoLevelInterpolant,
  613.             gTestLoLevelData.distance1,
  614.             gTestLoLevelData.distance2,
  615.             gTestLoLevelData.distanceRange);
  616.     
  617.     snd3DInfo.currentLocation.projectionAngle = TestLoLevel_DoInterpolate(
  618.             gTestLoLevelInterpolant,
  619.             gTestLoLevelData.projectionAngle1,
  620.             gTestLoLevelData.projectionAngle2,
  621.             gTestLoLevelData.projectionAngleDegRange);
  622.     
  623.     snd3DInfo.currentLocation.sourceVelocity = TestLoLevel_DoInterpolate(
  624.             gTestLoLevelInterpolant,
  625.             gTestLoLevelData.sourceVelocity1,
  626.             gTestLoLevelData.sourceVelocity2,
  627.             gTestLoLevelData.sourceVelocityRange);
  628.     
  629.     snd3DInfo.currentLocation.listenerVelocity = TestLoLevel_DoInterpolate(
  630.             gTestLoLevelInterpolant,
  631.             gTestLoLevelData.listenerVelocity1,
  632.             gTestLoLevelData.listenerVelocity2,
  633.             gTestLoLevelData.listenerVelocityRange);
  634.     
  635.     snd3DInfo.reserved0 = 0;
  636.     snd3DInfo.reserved1 = 0;
  637.     snd3DInfo.reserved2 = 0;
  638.     snd3DInfo.reserved3 = 0;
  639.     
  640.     snd3DInfo.virtualSourceCount = 0;
  641.     
  642.     // Make the filter changes
  643.     Sound_Set3DInfo(&snd3DInfo);
  644.     
  645.     // Update the progress bar
  646.     SetPort(gTestLoLevelDialog);
  647.     TestLoLevel_ProgressUserItem(gTestLoLevelDialog, kLoLevelItem_Progress);
  648. }
  649.  
  650.  
  651. /* =============================================================================
  652.  *        TestLoLevel_DoInterpolate (internal)
  653.  *
  654.  *    Linear interpolation.  When inWhere is zero, inVal0 is returned.  When it
  655.  *    is one, inVal1 is returned.  In between is linear.  If inIsRange is false
  656.  *    then we ignore inVal1 and always return inVal0.
  657.  * ========================================================================== */
  658. float TestLoLevel_DoInterpolate(
  659.     float                inWhere,
  660.     float                inVal0,
  661.     float                inVal1,
  662.     Boolean                inIsRange)
  663. {
  664.     float                result;
  665.     
  666.     if (inIsRange)
  667.     {
  668.         result = inWhere*(inVal1-inVal0) + inVal0;
  669.     }
  670.     else
  671.     {
  672.         result = inVal0;
  673.     }
  674.     
  675.     return result;
  676. }
  677.  
  678.  
  679. /* =============================================================================
  680.  *        TestLoLevel_DeriveData (internal)
  681.  *
  682.  *    Compute the derived fields in gTestLoLevelData.
  683.  * ========================================================================== */
  684. void TestLoLevel_DeriveData(
  685.     void)
  686. {
  687.     gTestLoLevelData.coneAngleCos1            = cosf(0.5*(_PI/180.0)*gTestLoLevelData.coneAngleDeg1);
  688.     gTestLoLevelData.coneAngleCos2            = cosf(0.5*(_PI/180.0)*gTestLoLevelData.coneAngleDeg2);
  689.     
  690.     gTestLoLevelData.longitude1                = (_PI/180.0)*gTestLoLevelData.longitudeDeg1;
  691.     gTestLoLevelData.longitude2                = (_PI/180.0)*gTestLoLevelData.longitudeDeg2;
  692.     
  693.     gTestLoLevelData.latitude1                = (_PI/180.0)*gTestLoLevelData.latitudeDeg1;
  694.     gTestLoLevelData.latitude2                = (_PI/180.0)*gTestLoLevelData.latitudeDeg2;
  695.     
  696.     gTestLoLevelData.projectionAngle1        = cosf((_PI/180.0)*gTestLoLevelData.projectionAngleDeg1);
  697.     gTestLoLevelData.projectionAngle2        = cosf((_PI/180.0)*gTestLoLevelData.projectionAngleDeg2);
  698. }
  699.  
  700.  
  701. /* =============================================================================
  702.  *        TestLoLevel_SetDialogFields (internal)
  703.  *
  704.  *    Changes the dialog's fields to reflect gTestLoLevelData.
  705.  * ========================================================================== */
  706. void TestLoLevel_SetDialogFields(
  707.     void)
  708. {
  709.     short                itemType;
  710.     Handle                itemHandle;
  711.     Rect                itemBounds;
  712.     short                value;
  713.     
  714.     Utils_SetFloatField(
  715.             gTestLoLevelDialog,
  716.             kLoLevelItem_Duration,
  717.             gTestLoLevelData.duration,
  718.             true);
  719.     
  720.     Utils_SetUInt32Field(
  721.             gTestLoLevelDialog,
  722.             kLoLevelItem_CPULoad1,
  723.             gTestLoLevelData.cpuLoad1,
  724.             true);
  725.     
  726.     Utils_SetUInt32Field(
  727.             gTestLoLevelDialog,
  728.             kLoLevelItem_CPULoad2,
  729.             gTestLoLevelData.cpuLoad2,
  730.             gTestLoLevelData.cpuLoadRange);
  731.     
  732.     GetDialogItem(gTestLoLevelDialog, kLoLevelItem_Medium, &itemType, &itemHandle, &itemBounds);
  733.     SetControlValue((ControlHandle) itemHandle,
  734.             (gTestLoLevelData.medium == kMediumWater)
  735.                     ? kMediumItem_Water
  736.                     : kMediumItem_Air);
  737.     
  738.     Utils_SetFloatField(
  739.             gTestLoLevelDialog,
  740.             kLoLevelItem_Humidity1,
  741.             gTestLoLevelData.humidity1,
  742.             true);
  743.     
  744.     Utils_SetFloatField(
  745.             gTestLoLevelDialog,
  746.             kLoLevelItem_Humidity2,
  747.             gTestLoLevelData.humidity2,
  748.             gTestLoLevelData.humidityRange);
  749.     
  750.     Utils_SetFloatField(
  751.             gTestLoLevelDialog,
  752.             kLoLevelItem_RoomSize1,
  753.             gTestLoLevelData.roomSize1,
  754.             true);
  755.     
  756.     Utils_SetFloatField(
  757.             gTestLoLevelDialog,
  758.             kLoLevelItem_RoomSize2,
  759.             gTestLoLevelData.roomSize2,
  760.             gTestLoLevelData.roomSizeRange);
  761.     
  762.     Utils_SetFloatField(
  763.             gTestLoLevelDialog,
  764.             kLoLevelItem_RoomReflectivity1,
  765.             gTestLoLevelData.roomReflectivity1,
  766.             true);
  767.     
  768.     Utils_SetFloatField(
  769.             gTestLoLevelDialog,
  770.             kLoLevelItem_RoomReflectivity2,
  771.             gTestLoLevelData.roomReflectivity2,
  772.             gTestLoLevelData.roomReflectivityRange);
  773.     
  774.     Utils_SetFloatField(
  775.             gTestLoLevelDialog,
  776.             kLoLevelItem_ReverbAttenuation1,
  777.             gTestLoLevelData.reverbAttenuation1,
  778.             true);
  779.     
  780.     Utils_SetFloatField(
  781.             gTestLoLevelDialog,
  782.             kLoLevelItem_ReverbAttenuation2,
  783.             gTestLoLevelData.reverbAttenuation2,
  784.             gTestLoLevelData.reverbAttenuationRange);
  785.     
  786.     value = kSourceModeItem_Localized;
  787.     switch (gTestLoLevelData.sourceMode)
  788.     {
  789.         case kSourceModeAmbient:
  790.             value = kSourceModeItem_Ambient;
  791.         break;
  792.         
  793.         case kSourceModeBinaural:
  794.             value = kSourceModeItem_Binaural;
  795.         break;
  796.     }
  797.     
  798.     GetDialogItem(gTestLoLevelDialog, kLoLevelItem_SourceMode, &itemType, &itemHandle, &itemBounds);
  799.     SetControlValue((ControlHandle) itemHandle, value);
  800.     
  801.     Utils_SetFloatField(
  802.             gTestLoLevelDialog,
  803.             kLoLevelItem_ReferenceDistance1,
  804.             gTestLoLevelData.referenceDistance1,
  805.             true);
  806.     
  807.     Utils_SetFloatField(
  808.             gTestLoLevelDialog,
  809.             kLoLevelItem_ReferenceDistance2,
  810.             gTestLoLevelData.referenceDistance2,
  811.             gTestLoLevelData.referenceDistanceRange);
  812.     
  813.     Utils_SetFloatField(
  814.             gTestLoLevelDialog,
  815.             kLoLevelItem_ConeAngleDeg1,
  816.             gTestLoLevelData.coneAngleDeg1,
  817.             true);
  818.     
  819.     Utils_SetFloatField(
  820.             gTestLoLevelDialog,
  821.             kLoLevelItem_ConeAngleDeg2,
  822.             gTestLoLevelData.coneAngleDeg2,
  823.             gTestLoLevelData.coneAngleDegRange);
  824.     
  825.     Utils_SetFloatField(
  826.             gTestLoLevelDialog,
  827.             kLoLevelItem_ConeAttenuation1,
  828.             gTestLoLevelData.coneAttenuation1,
  829.             true);
  830.     
  831.     Utils_SetFloatField(
  832.             gTestLoLevelDialog,
  833.             kLoLevelItem_ConeAttenuation2,
  834.             gTestLoLevelData.coneAttenuation2,
  835.             gTestLoLevelData.coneAttenuationRange);
  836.     
  837.     Utils_SetFloatField(
  838.             gTestLoLevelDialog,
  839.             kLoLevelItem_LongitudeDeg1,
  840.             gTestLoLevelData.longitudeDeg1,
  841.             true);
  842.     
  843.     Utils_SetFloatField(
  844.             gTestLoLevelDialog,
  845.             kLoLevelItem_LongitudeDeg2,
  846.             gTestLoLevelData.longitudeDeg2,
  847.             gTestLoLevelData.longitudeDegRange);
  848.     
  849.     Utils_SetFloatField(
  850.             gTestLoLevelDialog,
  851.             kLoLevelItem_LatitudeDeg1,
  852.             gTestLoLevelData.latitudeDeg1,
  853.             true);
  854.     
  855.     Utils_SetFloatField(
  856.             gTestLoLevelDialog,
  857.             kLoLevelItem_LatitudeDeg2,
  858.             gTestLoLevelData.latitudeDeg2,
  859.             gTestLoLevelData.latitudeDegRange);
  860.     
  861.     Utils_SetFloatField(
  862.             gTestLoLevelDialog,
  863.             kLoLevelItem_Distance1,
  864.             gTestLoLevelData.distance1,
  865.             true);
  866.     
  867.     Utils_SetFloatField(
  868.             gTestLoLevelDialog,
  869.             kLoLevelItem_Distance2,
  870.             gTestLoLevelData.distance2,
  871.             gTestLoLevelData.distanceRange);
  872.     
  873.     Utils_SetFloatField(
  874.             gTestLoLevelDialog,
  875.             kLoLevelItem_ProjectionAngleDeg1,
  876.             gTestLoLevelData.projectionAngleDeg1,
  877.             true);
  878.     
  879.     Utils_SetFloatField(
  880.             gTestLoLevelDialog,
  881.             kLoLevelItem_ProjectionAngleDeg2,
  882.             gTestLoLevelData.projectionAngleDeg2,
  883.             gTestLoLevelData.projectionAngleDegRange);
  884.     
  885.     Utils_SetFloatField(
  886.             gTestLoLevelDialog,
  887.             kLoLevelItem_SourceVelocity1,
  888.             gTestLoLevelData.sourceVelocity1,
  889.             true);
  890.     
  891.     Utils_SetFloatField(
  892.             gTestLoLevelDialog,
  893.             kLoLevelItem_SourceVelocity2,
  894.             gTestLoLevelData.sourceVelocity2,
  895.             gTestLoLevelData.sourceVelocityRange);
  896.     
  897.     Utils_SetFloatField(
  898.             gTestLoLevelDialog,
  899.             kLoLevelItem_ListenerVelocity1,
  900.             gTestLoLevelData.listenerVelocity1,
  901.             true);
  902.     
  903.     Utils_SetFloatField(
  904.             gTestLoLevelDialog,
  905.             kLoLevelItem_ListenerVelocity2,
  906.             gTestLoLevelData.listenerVelocity2,
  907.             gTestLoLevelData.listenerVelocityRange);
  908. }
  909.  
  910.  
  911. /* =============================================================================
  912.  *        TestLoLevel_GetDialogFields (internal)
  913.  *
  914.  *    Grabs the contents of the dialog fields and puts them into gTestLoLevelData.
  915.  * ========================================================================== */
  916. void TestLoLevel_GetDialogFields(
  917.     void)
  918. {
  919.     const float            small = 0.000001;
  920.     const float            big = 10000000.0;
  921.     short                itemType;
  922.     Handle                itemHandle;
  923.     Rect                itemBounds;
  924.     TTestLoLevelData    data;
  925.     short                badItem;
  926.     
  927.     if (!Utils_GetFloatField(
  928.             gTestLoLevelDialog,
  929.             kLoLevelItem_Duration,
  930.             &data.duration,
  931.             NULL,
  932.             small,
  933.             big))
  934.     {
  935.         badItem = kLoLevelItem_Duration;
  936.         goto bail;
  937.     }
  938.     
  939.     if (!Utils_GetUInt32Field(
  940.             gTestLoLevelDialog,
  941.             kLoLevelItem_CPULoad1,
  942.             &data.cpuLoad1,
  943.             NULL,
  944.             0,
  945.             gTestLoLevelCPULoadLimit))
  946.     {
  947.         badItem = kLoLevelItem_CPULoad1;
  948.         goto bail;
  949.     }
  950.     
  951.     if (!Utils_GetUInt32Field(
  952.             gTestLoLevelDialog,
  953.             kLoLevelItem_CPULoad2,
  954.             &data.cpuLoad2,
  955.             &data.cpuLoadRange,
  956.             0,
  957.             gTestLoLevelCPULoadLimit))
  958.     {
  959.         badItem = kLoLevelItem_CPULoad2;
  960.         goto bail;
  961.     }
  962.     
  963.     GetDialogItem(gTestLoLevelDialog, kLoLevelItem_Medium, &itemType, &itemHandle, &itemBounds);
  964.     switch (GetControlValue((ControlHandle) itemHandle))
  965.     {
  966.         case kMediumItem_Air:
  967.             data.medium = kMediumAir;
  968.         break;
  969.         
  970.         case kMediumItem_Water:
  971.             data.medium = kMediumWater;
  972.         break;
  973.         
  974.         default:
  975.             assert(0);
  976.     }
  977.     
  978.     if (!Utils_GetFloatField(
  979.             gTestLoLevelDialog,
  980.             kLoLevelItem_Humidity1,
  981.             &data.humidity1,
  982.             NULL,
  983.             0.0,
  984.             100.0))
  985.     {
  986.         badItem = kLoLevelItem_Humidity1;
  987.         goto bail;
  988.     }
  989.     
  990.     if (!Utils_GetFloatField(
  991.             gTestLoLevelDialog,
  992.             kLoLevelItem_Humidity2,
  993.             &data.humidity2,
  994.             &data.humidityRange,
  995.             0.0,
  996.             100.0))
  997.     {
  998.         badItem = kLoLevelItem_Humidity2;
  999.         goto bail;
  1000.     }
  1001.     
  1002.     if (!Utils_GetFloatField(
  1003.             gTestLoLevelDialog,
  1004.             kLoLevelItem_RoomSize1,
  1005.             &data.roomSize1,
  1006.             NULL,
  1007.             0.0,
  1008.             big))
  1009.     {
  1010.         badItem = kLoLevelItem_RoomSize1;
  1011.         goto bail;
  1012.     }
  1013.     
  1014.     if (!Utils_GetFloatField(
  1015.             gTestLoLevelDialog,
  1016.             kLoLevelItem_RoomSize2,
  1017.             &data.roomSize2,
  1018.             &data.roomSizeRange,
  1019.             0.0,
  1020.             big))
  1021.     {
  1022.         badItem = kLoLevelItem_RoomSize2;
  1023.         goto bail;
  1024.     }
  1025.     
  1026.     if (!Utils_GetFloatField(
  1027.             gTestLoLevelDialog,
  1028.             kLoLevelItem_RoomReflectivity1,
  1029.             &data.roomReflectivity1,
  1030.             NULL,
  1031.             -big,
  1032.             -small))
  1033.     {
  1034.         badItem = kLoLevelItem_RoomReflectivity1;
  1035.         goto bail;
  1036.     }
  1037.     
  1038.     if (!Utils_GetFloatField(
  1039.             gTestLoLevelDialog,
  1040.             kLoLevelItem_RoomReflectivity2,
  1041.             &data.roomReflectivity2,
  1042.             &data.roomReflectivityRange,
  1043.             -big,
  1044.             -small))
  1045.     {
  1046.         badItem = kLoLevelItem_RoomReflectivity2;
  1047.         goto bail;
  1048.     }
  1049.     
  1050.     if (!Utils_GetFloatField(
  1051.             gTestLoLevelDialog,
  1052.             kLoLevelItem_ReverbAttenuation1,
  1053.             &data.reverbAttenuation1,
  1054.             NULL,
  1055.             -big,
  1056.             big))
  1057.     {
  1058.         badItem = kLoLevelItem_ReverbAttenuation1;
  1059.         goto bail;
  1060.     }
  1061.     
  1062.     if (!Utils_GetFloatField(
  1063.             gTestLoLevelDialog,
  1064.             kLoLevelItem_ReverbAttenuation2,
  1065.             &data.reverbAttenuation2,
  1066.             &data.reverbAttenuationRange,
  1067.             -big,
  1068.             big))
  1069.     {
  1070.         badItem = kLoLevelItem_ReverbAttenuation2;
  1071.         goto bail;
  1072.     }
  1073.     
  1074.     GetDialogItem(gTestLoLevelDialog, kLoLevelItem_SourceMode, &itemType, &itemHandle, &itemBounds);
  1075.     switch (GetControlValue((ControlHandle) itemHandle))
  1076.     {
  1077.         case kSourceModeItem_Localized:
  1078.             data.sourceMode = kSourceModeLocalized;
  1079.         break;
  1080.         
  1081.         case kSourceModeItem_Ambient:
  1082.             data.sourceMode = kSourceModeAmbient;
  1083.         break;
  1084.         
  1085.         case kSourceModeItem_Binaural:
  1086.             data.sourceMode = kSourceModeBinaural;
  1087.         break;
  1088.         
  1089.         default:
  1090.             assert(0);
  1091.     }
  1092.     
  1093.     if (!Utils_GetFloatField(
  1094.             gTestLoLevelDialog,
  1095.             kLoLevelItem_ReferenceDistance1,
  1096.             &data.referenceDistance1,
  1097.             NULL,
  1098.             small,
  1099.             big))
  1100.     {
  1101.         badItem = kLoLevelItem_ReferenceDistance1;
  1102.         goto bail;
  1103.     }
  1104.     
  1105.     if (!Utils_GetFloatField(
  1106.             gTestLoLevelDialog,
  1107.             kLoLevelItem_ReferenceDistance2,
  1108.             &data.referenceDistance2,
  1109.             &data.referenceDistanceRange,
  1110.             small,
  1111.             big))
  1112.     {
  1113.         badItem = kLoLevelItem_ReferenceDistance2;
  1114.         goto bail;
  1115.     }
  1116.     
  1117.     if (!Utils_GetFloatField(
  1118.             gTestLoLevelDialog,
  1119.             kLoLevelItem_ConeAngleDeg1,
  1120.             &data.coneAngleDeg1,
  1121.             NULL,
  1122.             0.0,
  1123.             360.0))
  1124.     {
  1125.         badItem = kLoLevelItem_ConeAngleDeg1;
  1126.         goto bail;
  1127.     }
  1128.     
  1129.     if (!Utils_GetFloatField(
  1130.             gTestLoLevelDialog,
  1131.             kLoLevelItem_ConeAngleDeg2,
  1132.             &data.coneAngleDeg2,
  1133.             &data.coneAngleDegRange,
  1134.             0.0,
  1135.             360.0))
  1136.     {
  1137.         badItem = kLoLevelItem_ConeAngleDeg2;
  1138.         goto bail;
  1139.     }
  1140.     
  1141.     if (!Utils_GetFloatField(
  1142.             gTestLoLevelDialog,
  1143.             kLoLevelItem_ConeAttenuation1,
  1144.             &data.coneAttenuation1,
  1145.             NULL,
  1146.             -big,
  1147.             0.0))
  1148.     {
  1149.         badItem = kLoLevelItem_ConeAttenuation1;
  1150.         goto bail;
  1151.     }
  1152.     
  1153.     if (!Utils_GetFloatField(
  1154.             gTestLoLevelDialog,
  1155.             kLoLevelItem_ConeAttenuation2,
  1156.             &data.coneAttenuation2,
  1157.             &data.coneAttenuationRange,
  1158.             -big,
  1159.             0.0))
  1160.     {
  1161.         badItem = kLoLevelItem_ConeAttenuation2;
  1162.         goto bail;
  1163.     }
  1164.     
  1165.     if (!Utils_GetFloatField(
  1166.             gTestLoLevelDialog,
  1167.             kLoLevelItem_LongitudeDeg1,
  1168.             &data.longitudeDeg1,
  1169.             NULL,
  1170.             -180.0,
  1171.             180.0))
  1172.     {
  1173.         badItem = kLoLevelItem_LongitudeDeg1;
  1174.         goto bail;
  1175.     }
  1176.     
  1177.     if (!Utils_GetFloatField(
  1178.             gTestLoLevelDialog,
  1179.             kLoLevelItem_LongitudeDeg2,
  1180.             &data.longitudeDeg2,
  1181.             &data.longitudeDegRange,
  1182.             -180.0,
  1183.             180.0))
  1184.     {
  1185.         badItem = kLoLevelItem_LongitudeDeg2;
  1186.         goto bail;
  1187.     }
  1188.     
  1189.     
  1190.     if (!Utils_GetFloatField(
  1191.             gTestLoLevelDialog,
  1192.             kLoLevelItem_LatitudeDeg1,
  1193.             &data.latitudeDeg1,
  1194.             NULL,
  1195.             -90.0,
  1196.             90.0))
  1197.     {
  1198.         badItem = kLoLevelItem_LatitudeDeg1;
  1199.         goto bail;
  1200.     }
  1201.     
  1202.     if (!Utils_GetFloatField(
  1203.             gTestLoLevelDialog,
  1204.             kLoLevelItem_LatitudeDeg2,
  1205.             &data.latitudeDeg2,
  1206.             &data.latitudeDegRange,
  1207.             -90.0,
  1208.             90.0))
  1209.     {
  1210.         badItem = kLoLevelItem_LatitudeDeg2;
  1211.         goto bail;
  1212.     }
  1213.     
  1214.     if (!Utils_GetFloatField(
  1215.             gTestLoLevelDialog,
  1216.             kLoLevelItem_Distance1,
  1217.             &data.distance1,
  1218.             NULL,
  1219.             small,
  1220.             big))
  1221.     {
  1222.         badItem = kLoLevelItem_Distance1;
  1223.         goto bail;
  1224.     }
  1225.     
  1226.     if (!Utils_GetFloatField(
  1227.             gTestLoLevelDialog,
  1228.             kLoLevelItem_Distance2,
  1229.             &data.distance2,
  1230.             &data.distanceRange,
  1231.             small,
  1232.             big))
  1233.     {
  1234.         badItem = kLoLevelItem_Distance2;
  1235.         goto bail;
  1236.     }
  1237.     
  1238.     if (!Utils_GetFloatField(
  1239.             gTestLoLevelDialog,
  1240.             kLoLevelItem_ProjectionAngleDeg1,
  1241.             &data.projectionAngleDeg1,
  1242.             NULL,
  1243.             0.0,
  1244.             180.0))
  1245.     {
  1246.         badItem = kLoLevelItem_ProjectionAngleDeg1;
  1247.         goto bail;
  1248.     }
  1249.     
  1250.     if (!Utils_GetFloatField(
  1251.             gTestLoLevelDialog,
  1252.             kLoLevelItem_ProjectionAngleDeg2,
  1253.             &data.projectionAngleDeg2,
  1254.             &data.projectionAngleDegRange,
  1255.             0.0,
  1256.             180.0))
  1257.     {
  1258.         badItem = kLoLevelItem_ProjectionAngleDeg2;
  1259.         goto bail;
  1260.     }
  1261.     
  1262.     if (!Utils_GetFloatField(
  1263.             gTestLoLevelDialog,
  1264.             kLoLevelItem_SourceVelocity1,
  1265.             &data.sourceVelocity1,
  1266.             NULL,
  1267.             -big,
  1268.             big))
  1269.     {
  1270.         badItem = kLoLevelItem_SourceVelocity1;
  1271.         goto bail;
  1272.     }
  1273.     
  1274.     if (!Utils_GetFloatField(
  1275.             gTestLoLevelDialog,
  1276.             kLoLevelItem_SourceVelocity2,
  1277.             &data.sourceVelocity2,
  1278.             &data.sourceVelocityRange,
  1279.             -big,
  1280.             big))
  1281.     {
  1282.         badItem = kLoLevelItem_SourceVelocity2;
  1283.         goto bail;
  1284.     }
  1285.     
  1286.     if (!Utils_GetFloatField(
  1287.             gTestLoLevelDialog,
  1288.             kLoLevelItem_ListenerVelocity1,
  1289.             &data.listenerVelocity1,
  1290.             NULL,
  1291.             -big,
  1292.             big))
  1293.     {
  1294.         badItem = kLoLevelItem_ListenerVelocity1;
  1295.         goto bail;
  1296.     }
  1297.     
  1298.     if (!Utils_GetFloatField(
  1299.             gTestLoLevelDialog,
  1300.             kLoLevelItem_ListenerVelocity2,
  1301.             &data.listenerVelocity2,
  1302.             &data.listenerVelocityRange,
  1303.             -big,
  1304.             big))
  1305.     {
  1306.         badItem = kLoLevelItem_ListenerVelocity2;
  1307.         goto bail;
  1308.     }
  1309.     
  1310.     // All fields are good -- finish up
  1311.     gTestLoLevelData = data;
  1312.     TestLoLevel_DeriveData();
  1313.     
  1314.     TestLoLevel_SetDialogFields();
  1315.     
  1316.     return;
  1317.     
  1318.     // Error exit
  1319. bail:
  1320.     SelectDialogItemText(gTestLoLevelDialog, badItem, 0, 32767);
  1321.     StopAlert(kAlrtID_BadField, NULL);
  1322. }
  1323.  
  1324.  
  1325.